package com.AUI
{
	import com.AUI.components.*;
	import com.AUI.define.*;
	import com.AUI.events.*;
	
	import flash.display.*;
	import flash.events.*;
	import flash.utils.*;
	/**
	 * User Interface markup language document.
	 * @author HuangMinPing
	 * @site www.AminLab.com
	 */
	public class AXMLDocument
	{
		/**
		 * UIML define.
		 */
		private static const __DEFINE__:AXMLDefine = new AXMLDefine;
		/**
		 * Cascading style sheets.
		 */
		public var css:ACss;
		/**
		 * Top node.
		 */
		public var dom:Container;
		/**
		 * Script Domain.
		 */
		private var _scriptDomain:Object;
		/**
		 * IDs.
		 */
		private var _ids:Dictionary = new Dictionary;
		/**
		 * Constructor.
		 */
		public function AXMLDocument(scriptDomain:Object)
		{
			_scriptDomain = scriptDomain;
		}
		/**
		 * Load xml file(UIML format).
		 */
		public function parseXML(file:XML):void
		{
			css = AUIGlobal.currentCss;
			ACssParser.parse(file.style[0].toString(),css);
			dom = parseDOM(file.layout[0]);
		}
		/**
		 * Parse DOM.
		 */
		public function parseDOM(xml:XML):Container
		{
			var node:Container = new Container;
			var children:XMLList = xml.children();
			for(var i:int = 0,len:int = children.length();i < len;++i)
			{
				node.addElement(parseNode(children[i],node));
			}
			return node;
		}
		/**
		 * Parse node.
		 */
		private function parseNode(xml:XML,parentNode:Container = null):AComponent
		{	
			var i:int
			var len:int;
			// 1.get node class
			var nodeName:String = xml.name().toString().toLocaleLowerCase();
			var nodeClass:Class = __DEFINE__.tag[nodeName];
			// 2.create node
			var node:AComponent = new nodeClass;
			node.ename     = nodeName;
			node.idName    = xml.@id;
			node.className = xml.attribute('class');
			node.style.mix(css.getStyle('#'+ node.idName));
			node.style.mix(css.getStyle('.'+ node.className));
			node.updateStyle();
			// 3.init node attributes
			var attrs:XMLList = xml.attributes();
			for(i = 0,len = attrs.length();i < len;++i)
			{
				var attr:XML = attrs[i];
				var attrName:String  = attr.name();
				var attrValue:String = attr;
				switch(attrName.toLowerCase())
				{
					case 'disabled':
						node.disabled = (attrValue == 'true' ? true : false);
						break;
					case 'id':
						_ids[attrValue] = node;
						break;
					case 'onitemclick':
						node.addEventListener(AItemEvent.CLICK,_scriptDomain[attrValue],false,0,true);
						break;
					case 'visible':
						node.visible = (attrValue == 'true' ? true : false);
						break;
					case 'onclick':
						node.addEventListener(MouseEvent.CLICK,_scriptDomain[attrValue],false,0,true);
						break;
					case 'onenter':
						node.addEventListener('enter',_scriptDomain[attrValue],false,0,true);
						break;
					case 'x':
						node.x = parseInt(attrValue);
						break;
					case 'y':
						node.y = parseInt(attrValue);
						break;
					case 'readonly':
						node['readonly'] = (attrValue == 'true' ? true : false);
						break;
					case 'maxlength':
						node['maxLength'] = parseInt(attrValue);
						break;
				}
			}
			//trace(node.idName,node.height);
			// 4.create child nodes
			var children:XMLList = xml.children();
			for(i = 0,len = children.length();i < len;++i)
			{
				var childXML:XML = children[i];
				var childKind:String = childXML.nodeKind();
				if(childKind == 'element')
				{
					var child:AComponent = parseNode(childXML,Container(node));
					Container(node).addElement(child);
				}
				else
				{
					node.value = childXML.toString();
				}
			}
			return node;
		}
		/**
		 * Get a element by id.
		 */
		public function getElementById(value:String):AComponent
		{
			return _ids[value];
		}
	}
}